#!/usr/bin/python

import fuse
fuse.fuse_python_api = (0, 2)

import subprocess
import urllib
import stat    # for file properties
import os      # for filesystem modes (O_RDONLY, etc)
import sys
import errno   # for error number codes (ENOENT, etc)
               # - note: these must be returned as negatives

import logging
logger = logging.getLogger(__name__)

class SearchFS(fuse.Fuse):

    def __init__(self, mountdir):
        fuse.Fuse.__init__(self)
        self.mountdir = mountdir
        self.query_cache = {}

        logger.info('Init complete.')

    @classmethod
    def parse(cls, path):
        return tuple(filter(bool, path.split('/')))
    
    def getattr(self, path):
        logger.debug('getattr: %r', path)

        if path.endswith('/.hidden'):
            return  -errno.ENOSYS

        query = self.parse(path)[:-1]
        if query in self.query_cache and path in self.query_cache[query]:
            return fuse.Stat(st_mode=stat.S_IFLNK | 0777, st_nlink=1)
        else:
            return fuse.Stat(st_mode=stat.S_IFDIR | 0777, st_nlink=1)
        return -errno.ENOSYS

    def readdir(self, path, offset):
        logger.debug("read dir: %r", path)
        
        query = self.parse(path)
        ql = len(query)

        dirs = set(q[ql] for q in self.query_cache.keys() if q[:ql]==query and len(q)>ql)
        for d in sorted(dirs):
            yield fuse.Direntry(d)

        if query:
            self.query_cache[query] = result = {}
            for line in subprocess.check_output(('tracker-search',) + query).split('\n'):
                line = line.strip()
                if line.startswith('file://'):
                    destpath = urllib.unquote(line[7:])
                    fn = destpath.split('/')[-1]
                    result[path + '/' + fn] = destpath
                    yield fuse.Direntry(fn)

    def readlink ( self, path ):
        logger.debug('readlink: %r', path)
        query = self.parse(path)[:-1]
        if query  in self.query_cache and path in self.query_cache[query]:
            return self.query_cache[query][path]
        return -errno.ENOSYS
            
    def mkdir ( self, path, mode ):
        logger.debug('mkdir: %r %r', path, oct(mode))
        return -errno.ENOSYS

    def rmdir ( self, path ):
        logger.debug('rmdir: %r', path)
        for k in tuple(self.query_cache.keys()):
            if k == path or k.startswith(path + '/'):
                del self.query_cache[k]

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)
    fs = SearchFS(sys.argv[1])
    fs.flags = 0
    fs.multithreaded = 0
    fs.main(sys.argv)
